{{*/*
  * Simple Date
  * A simple date/time which can be serialized easily.
  */*}}

{{*/*
  * Constructor.
  * This object should never be instantiated.
  */*}}
function SimpleDate() {
};

{{*/*
  * Creates a new simple date, no arguments uses the current time.
  * @param year The full 4 digit year
  * @param month The month
  * @param date The date
  * @param hours The hours
  * @param minutes The minutes
  * @param seconds The seconds
  * @return A simple date
  */*}}
SimpleDate.create = function(year, month, date, hours, minutes, seconds) {
  if (!arguments.length) {
    var d = new Date();
    d.setHours(0);
    d.setMinutes(0);
    d.setSeconds(0);
    return this.fromDate(d);
  }
  return { year: (year != null) ? year : 0,
           month: (month != null) ? month : 0,
           date: (date != null) ? date : 0,
           hours: (hours != null) ? hours : 12,
           minutes: (minutes != null) ? minutes : 0,
           seconds: (seconds != null) ? seconds : 0 };
};

{{*/*
  * Clones a date.
  * @param sd The simple date
  * @return The clones simple date
  */*}}
SimpleDate.clone = function(sd) {
  if (!sd) {
    return null;
  }

  return SimpleDate.create(sd.year, sd.month, sd.date, sd.hours, sd.minutes, sd.seconds);
};

{{*/*
  * Creates a new simple date from an XML attribute.
  * @param qdate Date attribute in YYYY-mm-dd format
  * @param qtime Time attribute in HH:MM format
  * @return A simple date
  */*}}
SimpleDate.fromAttr = function(qdate, qtime) {
  var sd = this.create(0, 0, 0);
  var parts;

  if (qdate) {
    parts = qdate.split('-');
    if (parts.length == 3) {
      sd.year = parseInt(parts[0], 10);
      sd.month = parseInt(parts[1], 10);
      sd.date = parseInt(parts[2], 10);
    }
  }

  if (qtime) {
    parts = qtime.split(':');
    if (parts.length == 2) {
      sd.hours = parseInt(parts[0], 10);
      sd.minutes = parseInt(parts[1], 10);
    }
  }

  return sd;
};

{{*/*
  * Creates a new simple date from a date object.
  * @param d The date
  * @return A simple date or null if the date is null
  */*}}
SimpleDate.fromDate = function(d) {
  if (!d) {
    return this.create(0, 0, 0);
  }
  return this.create(d.getFullYear(), d.getMonth() + 1, d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds());
};

{{*/*
  * Creates a new simple date from a time stamp.
  * @param stamp The unix time stamp in seconds
  * @return A simple date
  */*}}
SimpleDate.fromStamp = function(stamp) {
  return this.fromDate(new Date(stamp * 1000));
};

{{*/*
  * Converts a simple date to a date object.
  * @param sd The simple date
  * @return A new date object or null
  */*}}
SimpleDate.toDate = function(sd) {
  if (!sd) {
    return null;
  }

  return new Date(sd.year, sd.month - 1, sd.date, sd.hours, sd.minutes, sd.seconds);
};

{{*/*
  * Converts a simple date to a time stamp.
  * @param sd The simple date
  * @return The unix time stamp in seconds or null.
  */*}}
SimpleDate.toStamp = function(sd) {
  if (!arguments.length) {
    return (new Date().getTime()) / 1000;
  }

  if (!sd) {
    return null;
  }

  var d = this.toDate(sd);
  return (d) ? (d.getTime() / 1000) : 0;
};

{{*/*
  * Formats a simple date for display.
  * @param sd The simple date
  * @param showTime Also display the time
  * @return String representation of the simple date
  */*}}
SimpleDate.format = function(sd, showTime, asMeridiem) {
  if (!sd) {
    return 'Unknown';
  }

  if (!showTime) {
    return SimpleDate.fmtDigits(sd.date) + '/' + SimpleDate.fmtDigits(sd.month) + '/' + sd.year;
  }

  if (asMeridiem) {
    var meridiem, hours;
    if (sd.hours < 12) {
      hours = sd.hours;
      meridiem = 'AM';
    } else {
      hours = sd.hours - 12;
      meridiem = 'PM';
    }
    return SimpleDate.fmtDigits(sd.date) + '/' + SimpleDate.fmtDigits(sd.month) + '/' + sd.year + ' ' + SimpleDate.fmtDigits(sd.hours) + ':' + SimpleDate.fmtDigits(sd.minutes) + ' ' + meridiem;
  }

  return SimpleDate.fmtDigits(sd.date) + '/' + SimpleDate.fmtDigits(sd.month) + '/' + sd.year + ' ' + SimpleDate.fmtDigits(sd.hours) + ':' + SimpleDate.fmtDigits(sd.minutes);
};

{{*/*
  * Adds a leading '0' to a number if less than 10
  * @param num The number
  * @return The formatted number
  */*}}
SimpleDate.fmtDigits = function(num) {
  return (num < 10) ? ('0' + num) : num;
};

{{*/*
  * Checks if a simple date's date section is used.
  * @param sd The simple date
  * @return If the date is used
  */*}}
SimpleDate.hasDate = function(sd) {
  return (sd) ? ((((sd.year !== null) && (sd.year > 0)) && ((sd.month !== null) && (sd.month > 0)) && ((sd.date !== null) && (sd.date > 0))) ? true : false) : false;
};

{{*/*
  * Checks if a simple date's time section is used.
  * @param sd The simple date
  * @return If the time is used
  */*}}
SimpleDate.hasTime = function(sd) {
  return (sd) ? (((sd.hours > 0) || (sd.minutes > 0) || (sd.seconds > 0)) ? true : false) : false;
};
